using System;
using System.Timers;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.VisualStyles;
using ff14bot;
using ff14bot.Behavior;
using ff14bot.Enums;
using ff14bot.Managers;
using ff14bot.Navigation;
using ff14bot.Objects;
using ff14bot.Helpers;
using Kupper;
using Kupper.Helpers;
using Kupper.Settings;
using Pathfinding;
using TreeSharp;
using Action = TreeSharp.Action;
using System.Windows.Input;
using System.Windows.Forms;

namespace Kupper.Rotations
{
    public class RogueNinja : KupperRoutine
    {
        //DEVELOPERS REPLACE GetType().Name WITH YOUR CR'S NAME.
        public override string Name
        {
            get { return "Kupper [" + GetType().Name + "]"; }
        }
		
		public override void OnInitialize()
        {
            WindowSettings = new NinjaSettings();
			Kupper.Settings.NinjaSettings.MudraState = "Ninjutsu";
			Kupper.Settings.NinjaSettings.lastspellused = "Ninjutsu";
			HotkeyManager.Register("AOE Toggle", Keys.Z, ModifierKeys.Shift, r => settings.AutoAOE = !settings.AutoAOE);
        }

        private NinjaSettings settings
        {
            get { return WindowSettings as NinjaSettings; }
        }

        public override float PullRange
        {
            get { return 2.5f; }
        }

        public override ClassJobType[] Class
        {
            get { return new ClassJobType[] {ClassJobType.Rogue, ClassJobType.Ninja,}; }
        }

		public SpellData SkillBlocker;
		public SpellData SATATimer;
		public SpellData NinjutsuTimer;
		public static System.Timers.Timer MTimer;
		public static int MudraTimerActive = 0;
		public static string NinjutsuState = "Nothing";
		
		public static void MudraTimer()
		{
			if(MudraTimerActive == 0){
				MTimer = new System.Timers.Timer(2000);
				MudraTimerActive = 1;
				}
			
			MTimer.Elapsed += MudraReset;
			MTimer.AutoReset = false;
			MTimer.Enabled = false;
			MTimer.Enabled = true;
		}
		
		public static void MudraReset(object sender, ElapsedEventArgs e)
		{
			if(!Core.Me.HasAura("Mudra") && Kupper.Settings.NinjaSettings.lastspellused != "Ninjutsu"){
				Kupper.Settings.NinjaSettings.MudraState = "Ninjutsu";
				Kupper.Settings.NinjaSettings.lastspellused = "Ninjutsu";
				Logging.Write("Mudra failed. Resetting.");
				}
		}
		
		public override void OnPulse()
        {
		Actionmanager.CurrentActions.TryGetValue("Spinning Edge", out SkillBlocker);
		Actionmanager.CurrentActions.TryGetValue("Sneak Attack", out SATATimer);
		Actionmanager.CurrentActions.TryGetValue("Ten", out NinjutsuTimer);

		if(settings.UseDebug){
		Logging.Write("Ninjutsu Cooldown = " + NinjutsuTimer.Cooldown.TotalMilliseconds);
		Logging.Write("lastspellused = " + Kupper.Settings.NinjaSettings.lastspellused);
		Logging.Write("MudraState = " + Kupper.Settings.NinjaSettings.MudraState);
		Logging.Write("NinjutsuState = " + NinjutsuState);
		Logging.Write("Skillblocker = " + SkillBlocker.Cooldown.TotalMilliseconds);
		Logging.Write("Mudra active = " + Core.Me.HasAura("Mudra"));
		}
		

	
		if(Actionmanager.CurrentActions.TryGetValue("Ten", out NinjutsuTimer)){
			if(NinjutsuTimer.Cooldown.TotalMilliseconds >= 1 && NinjutsuTimer.Cooldown.TotalMilliseconds <= 499){
				Kupper.Settings.NinjaSettings.MudraState = Kupper.Settings.NinjaSettings.lastspellused;
				MudraTimer();
			}
						
			if(NinjutsuTimer.Cooldown.TotalMilliseconds >= 501 && NinjutsuTimer.Cooldown.TotalMilliseconds <= 19999 && !Core.Me.HasAura("Mudra")){
				Kupper.Settings.NinjaSettings.MudraState = "Ninjutsu";
				Kupper.Settings.NinjaSettings.lastspellused = "Ninjutsu";
			}
						
		}

		if(Kupper.Settings.NinjaSettings.lastspellused == "Ninjutsu" && !Core.Me.HasAura("Mudra") && Core.Me.HasTarget){
			if(
				settings.UseFumaShuriken &&
				(Core.Me.ClassLevel < 35 || settings.FumaTargets.Contains(Core.Me.CurrentTarget.Name) || !settings.UseRaiton)
				)
				NinjutsuState = "Fuma Shuriken";
			if(
				settings.UseRaiton && 
				Core.Me.ClassLevel >= 35 && 
				!settings.FumaTargets.Contains(Core.Me.CurrentTarget.Name) &&
				(SATATimer.Cooldown.TotalMilliseconds >= 1000 || !settings.UseSuiton || Core.Me.ClassLevel <= 45 || (Core.Me.HasAura("Kassatsu") && !settings.KassatsuSuiton) || Core.Me.HasAura("Suiton"))
				)
					NinjutsuState = "Raiton";
			if(
				settings.UseDoton &&
				Core.Me.ClassLevel >= 45 && 
				((EnemiesNearMe(5) >= settings.AOENinjutsuLimit && !settings.DontAOE.Contains(Core.Me.CurrentTarget.Name) && settings.AutoAOE) || settings.AOEOverride) &&
				!Core.Me.HasAura("Doton", true, 6000) &&
				(!Core.Me.HasAura("Kassatsu") || settings.KassatsuDoton)
				)
					NinjutsuState = "Doton";
			if(
				settings.UseSuiton && 
				Core.Me.ClassLevel >= 45 && 
				!Core.Me.HasAura("Suiton") &&
				SATATimer.Cooldown.TotalMilliseconds <= 1000 && 
				(!Core.Me.HasAura("Kassatsu") || settings.KassatsuSuiton) &&
				((((EnemiesNearMe(5) < settings.AOENinjutsuLimit || settings.DontAOE.Contains(Core.Me.CurrentTarget.Name))  && (settings.AutoAOE || settings.AOEOverride)) || (!settings.AutoAOE && !settings.AOEOverride)) || Core.Me.HasAura("Doton", false, 6000) || (Core.Me.HasAura("Kassatsu") && !settings.KassatsuDoton))
				)
					NinjutsuState = "Suiton";
			if(
				settings.UseHuton &&
				!Core.Me.HasAura("Huton", true, settings.HutonClip) && 
				Core.Me.ClassLevel >= 45 && 
				(!Core.Me.HasAura("Kassatsu") || settings.KassatsuHuton) &&
				((settings.AOEHuton && (settings.AutoAOE || settings.AOEOverride)) || (!settings.AutoAOE && !settings.AOEOverride))
				)
					NinjutsuState = "Huton";
			if(Core.Me.CurrentTarget.CurrentHealth < settings.NinjutsuHPLimit)
				NinjutsuState = "Target HP too low";
		}
		
		ChocoboStanceCheck();
		
		}

/* 		public Composite UsePotion(string PotName, GameObject onTarget)
		{
			var pot = InventoryManager.FilledSlots.FirstOrDefault(a => a.Name.Equals(PotName) && a.IsHighQuality);
				return new Decorator(r => pot != null && onTarget == Core.Me && pot.IsValid && pot.CanUse(onTarget) && settings.UseBuffPotions, new Action(r => {
					pot.UseItem(onTarget);
				}));
				return new Decorator(r => pot != null && onTarget != Core.Me && pot.IsValid && pot.CanUse(onTarget) && settings.UsePoisonPotions, new Action(r => {
					pot.UseItem(onTarget);
				}));
		} */
		
		[Behavior(BehaviorType.PreCombatBuffs)]
        public Composite CreateBasicPreCombatBuffs()
        {
            return SummonChocobo();
        }

        [Behavior(BehaviorType.Rest)]
        public Composite CreateBasicRest()
        {
            return DefaultRestBehavior(r => Core.Me.CurrentTPPercent);
        }

        [Behavior(BehaviorType.Pull)]
        public Composite CreateBasicPull()
        {
		return new PrioritySelector(ctx => Core.Me.CurrentTarget as BattleCharacter,
            new Decorator(ctx => ctx != null && BotManager.Current.IsAutonomous,
                new PrioritySelector(
                    CommonBehaviors.MoveToLos(ctx => ctx as GameObject),
                    CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => PullRange + (ctx as GameObject).CombatReach, true, "Moving to unit")
					)
				),
				NinjaCombat()


			);
        }

        [Behavior(BehaviorType.Combat)]
        public Composite CreateBasicCombat()
        {
			return new PrioritySelector(ctx => Core.Me.CurrentTarget as BattleCharacter,
                new Decorator(ctx => ctx != null && BotManager.Current.IsAutonomous,
                    new PrioritySelector(
                        CommonBehaviors.MoveToLos(ctx => ctx as GameObject),
                        CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => PullRange + (ctx as GameObject).CombatReach, true, "Moving to unit")
						)
					),
				NinjaCombat()


			);
        }
		
		public static BattleCharacter _goadtarget;
        private static List<BattleCharacter> _partyList;
		
		
		public BattleCharacter Goadtarget()
		{
			
			_partyList = new List<BattleCharacter>();
			_partyList.AddRange(PartyManager.VisibleMembers.Select(o => o.GameObject as BattleCharacter));
			_partyList = _partyList.Where(u => Core.Player.Distance(u) <= 30 && u.InLineOfSight()).ToList();
			
			_goadtarget = (from battleCharacter in _partyList
			orderby battleCharacter.CurrentTP ascending
			where battleCharacter.CurrentTP < 1000 && battleCharacter.CurrentHealth > 1 &&
			(battleCharacter.CurrentJob == ClassJobType.Ninja ||
			battleCharacter.CurrentJob == ClassJobType.Dragoon ||
			battleCharacter.CurrentJob == ClassJobType.Monk ||
			battleCharacter.CurrentJob == ClassJobType.Bard ||
			battleCharacter.CurrentJob == ClassJobType.Rogue ||
			battleCharacter.CurrentJob == ClassJobType.Lancer ||
			battleCharacter.CurrentJob == ClassJobType.Pugilist ||
			battleCharacter.CurrentJob == ClassJobType.Archer)
			select battleCharacter).FirstOrDefault();
			
			return _goadtarget;
		}
		
		public Composite NinjaCombat()
		{
		
		    return new PrioritySelector(
				//Interrupts
				new Decorator(r => settings.UseInterrupt && settings.UseJugulate && settings.Interrupt.Contains((Core.Me.CurrentTarget as BattleCharacter).SpellCastInfo.Name), 
					new PrioritySelector(
						Spell.Cast("Jugulate")
						)
					),
				
				//SATA
				new Decorator(r =>
				
					(Core.Me.HasAura("Hidden") || Core.Me.HasAura("Suiton")) &&
					!Core.Me.HasAura("Mudra"),
				
					new PrioritySelector(
						Spell.Cast("Trick Attack", r => Core.Me.CurrentTarget.IsBehind && settings.UseTrickAttack),
						Spell.Cast("Sneak Attack", r => !Core.Me.CurrentTarget.IsBehind && !Core.Me.CurrentTarget.IsFlanking && settings.UseSneakAttack)
						)
					),
					
				//Kassatsu
				new Decorator(r => Actionmanager.CurrentActions.TryGetValue("Ten", out NinjutsuTimer),
					new PrioritySelector(
						Spell.Cast(r => "Kassatsu", r => NinjutsuTimer.Cooldown.TotalMilliseconds >= settings.KassatsuTimer && !Core.Me.HasAura("Mudra") && settings.UseKassatsu && (SkillBlocker.Cooldown.TotalMilliseconds >= 1001 || Core.Me.CurrentTP <=50 || (SkillBlocker.Cooldown.TotalMilliseconds == 0 && !Actionmanager.CanCast("Spinning Edge", Core.Me.CurrentTarget))), r => Core.Me)
						)
					),

				//AOE
					
				new Decorator(r => settings.AutoAOE || settings.AOEOverride,
					new PrioritySelector(
						Spell.Cast(r => "Death Blossom", r => Kupper.Settings.NinjaSettings.lastspellused == "Ninjutsu" && !Core.Me.HasAura("Mudra") && Core.Me.CurrentTP >= settings.AOETPLimit && (settings.AOEOverride || settings.AOEMeleeLimit <= EnemiesNearMe(5)) && !settings.DontAOE.Contains(Core.Me.CurrentTarget.Name), r => Core.Me)
						)
					),
					
				//Doton
				new Decorator(r => 
				
					NinjutsuState == "Doton"
					,
					new PrioritySelector(
						Spell.Cast(r => "Ten", r => Kupper.Settings.NinjaSettings.MudraState == "Ninjutsu" && !Core.Me.HasAura("Mudra") && (SkillBlocker.Cooldown.TotalMilliseconds >= 1001 || Core.Me.CurrentTP <=50 || (SkillBlocker.Cooldown.TotalMilliseconds == 0 && !Actionmanager.CanCast("Spinning Edge", Core.Me.CurrentTarget))), r => Core.Me),
						Spell.Cast(r => "Jin", r => Kupper.Settings.NinjaSettings.MudraState == "Ten" && Core.Me.HasAura("Mudra"), r => Core.Me),
						Spell.Cast(r => "Chi", r => Kupper.Settings.NinjaSettings.MudraState == "Jin" && Core.Me.HasAura("Mudra"), r => Core.Me),
						Spell.Cast(r => "Ninjutsu", r => Kupper.Settings.NinjaSettings.MudraState == "Chi" && Core.Me.HasAura("Mudra"), r => Core.Me, true)
						)
					),
				
				//Huton
				new Decorator(r =>
				
					NinjutsuState == "Huton"
					,
					new PrioritySelector(
						Spell.Cast(r => "Jin", r => Kupper.Settings.NinjaSettings.MudraState == "Ninjutsu" && !Core.Me.HasAura("Mudra") && (SkillBlocker.Cooldown.TotalMilliseconds >= 1001 || Core.Me.CurrentTP <=50 || (SkillBlocker.Cooldown.TotalMilliseconds == 0 && !Actionmanager.CanCast("Spinning Edge", Core.Me.CurrentTarget))), r => Core.Me),
						Spell.Cast(r => "Chi", r => Kupper.Settings.NinjaSettings.MudraState == "Jin" && Core.Me.HasAura("Mudra"), r => Core.Me),
						Spell.Cast(r => "Ten", r => Kupper.Settings.NinjaSettings.MudraState == "Chi" && Core.Me.HasAura("Mudra"), r => Core.Me),
						Spell.Cast(r => "Ninjutsu", r => Actionmanager.CanCast("Ninjutsu", Core.Me) && Kupper.Settings.NinjaSettings.MudraState == "Ten" && Core.Me.HasAura("Mudra"), r => Core.Me, true),
/*Just in case...*/		Spell.Cast(r => "Ninjutsu", r => Actionmanager.CanCast("Ninjutsu", Core.Me.CurrentTarget) && Kupper.Settings.NinjaSettings.MudraState == "Ten" && Core.Me.HasAura("Mudra"), r => Core.Me.CurrentTarget, true)
						)
					),
				
				//Suiton
				
				new Decorator(r =>
				
					NinjutsuState == "Suiton"
					,
					new PrioritySelector(
						Spell.Cast(r => "Ten", r => Kupper.Settings.NinjaSettings.MudraState == "Ninjutsu" && !Core.Me.HasAura("Mudra") && (SkillBlocker.Cooldown.TotalMilliseconds >= 1001 || Core.Me.CurrentTP <=50 || (SkillBlocker.Cooldown.TotalMilliseconds == 0 && !Actionmanager.CanCast("Spinning Edge", Core.Me.CurrentTarget))), r => Core.Me),
						Spell.Cast(r => "Chi", r => Kupper.Settings.NinjaSettings.MudraState == "Ten" && Core.Me.HasAura("Mudra"), r => Core.Me),
						Spell.Cast(r => "Jin", r => Kupper.Settings.NinjaSettings.MudraState == "Chi" && Core.Me.HasAura("Mudra"), r => Core.Me),
						Spell.Cast(r => "Ninjutsu", r => Actionmanager.CanCast("Ninjutsu", Core.Me) && Kupper.Settings.NinjaSettings.MudraState == "Jin" && Core.Me.HasAura("Mudra"), r => Core.Me.CurrentTarget, true)
						)
					),
				
				//Raiton
				new Decorator(r => 
					
					NinjutsuState == "Raiton"
					,
					new PrioritySelector(
						Spell.Cast(r => "Ten", r => Kupper.Settings.NinjaSettings.MudraState == "Ninjutsu" && !Core.Me.HasAura("Mudra") && (SkillBlocker.Cooldown.TotalMilliseconds >= 1001 || Core.Me.CurrentTP <=50 || (SkillBlocker.Cooldown.TotalMilliseconds == 0 && !Actionmanager.CanCast("Spinning Edge", Core.Me.CurrentTarget))), r => Core.Me),
						Spell.Cast(r => "Chi", r => Kupper.Settings.NinjaSettings.MudraState == "Ten" && Core.Me.HasAura("Mudra"), r => Core.Me),
						Spell.Cast(r => "Ninjutsu", r => Actionmanager.CanCast("Ninjutsu", Core.Me) && Kupper.Settings.NinjaSettings.MudraState == "Chi" && Core.Me.HasAura("Mudra"), r => Core.Me.CurrentTarget, true)
						)
					),
					
				
				
				//Fuma Shuriken
				new Decorator(r => 
				
					NinjutsuState == "Fuma Shuriken"
					,
					new PrioritySelector(
						Spell.Cast(r => "Ten", r => Kupper.Settings.NinjaSettings.MudraState == "Ninjutsu" && !Core.Me.HasAura("Mudra") && (SkillBlocker.Cooldown.TotalMilliseconds >= 1001 || Core.Me.CurrentTP <=50 || (SkillBlocker.Cooldown.TotalMilliseconds == 0 && !Actionmanager.CanCast("Spinning Edge", Core.Me.CurrentTarget))), r => Core.Me),
						Spell.Cast(r => "Ninjutsu", r => Actionmanager.CanCast("Ninjutsu", Core.Me) && Kupper.Settings.NinjaSettings.MudraState == "Ten" && Core.Me.HasAura("Mudra"), r => Core.Me.CurrentTarget, true)
						)
					),
		
				//Buffs
				new Decorator(r => 
					Kupper.Settings.NinjaSettings.lastspellused == "Ninjutsu" && 
					!Core.Me.HasAura("Mudra") &&
					settings.UseBuffs && 
					Core.Me.CurrentTarget.CurrentHealth >= settings.BuffHPLimit && 
					SkillBlocker.Cooldown.TotalMilliseconds >= 1000, 
					
					new PrioritySelector(
						Spell.Cast("Kiss of the Wasp", r => !Core.Me.HasAura("Kiss of the Wasp") && ((settings.UseWasp && !settings.UseViper) || (settings.UseWasp && !Actionmanager.HasSpell("Kiss of the Viper"))), r => Core.Me),
						Spell.Cast("Kiss of the Viper", r => !Core.Me.HasAura("Kiss of the Viper") && settings.UseViper, r => Core.Me),
						Spell.Cast("Blood for Blood", r => !Core.Me.HasAura("Blood for Blood") && settings.UseBloodForBlood, r => Core.Me),
						Spell.Cast("Internal Release", r => !Core.Me.HasAura("Internal Release") && settings.UseInternalRelease, r => Core.Me)
//						UsePotion("X-Potion of Dexterity", Core.Me)
						)
					),

				//GCDs / Main Combo
				new Decorator(r => Kupper.Settings.NinjaSettings.lastspellused == "Ninjutsu" && !Core.Me.HasAura("Mudra"),			
					new PrioritySelector(
						Spell.Cast("Mutilate", r => 
							(!Core.Me.CurrentTarget.HasAura("Mutilation", true, settings.MutilateClip) && (Core.Me.CurrentTarget.HasAura("Shadow Fang") || Core.Me.ClassLevel < 46) && Core.Me.CurrentTarget.CurrentHealth >= settings.DOTLimit) && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name) &&
								(
								(Actionmanager.LastSpell.Name == "Spinning Edge" && Core.Me.ClassLevel < 4) ||
								(Actionmanager.LastSpell.Name == "Gust Slash" && Core.Me.ClassLevel < 26) ||
								(Actionmanager.LastSpell.Name == "Shadow Fang") ||
								(Actionmanager.LastSpell.Name == "Aeolian Edge") ||
								(Actionmanager.LastSpell.Name == "Dancing Edge") ||
								(Actionmanager.LastSpell.Name == "Mutilate") ||
								(Actionmanager.LastSpell.Name == "EmptySpell")
								)),							
						Spell.Cast("Dancing Edge", r => 
							Actionmanager.LastSpell.Name == "Gust Slash" && 
							(!Core.Me.CurrentTarget.HasAura("Dancing Edge", false, settings.DancingEdgeClip) &&	!Core.Me.CurrentTarget.HasAura("Storm's Eye", false)) && 
							settings.UseDancingEdge),
						Spell.Cast("Aeolian Edge", r => Actionmanager.LastSpell.Name == "Gust Slash"),
						Spell.Cast("Shadow Fang", r => Actionmanager.LastSpell.Name == "Spinning Edge" && !Core.Me.CurrentTarget.HasAura("Shadow Fang", true, settings.ShadowFangClip) && Core.Me.CurrentTarget.CurrentHealth >= settings.DOTLimit && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name)),
						Spell.Cast("Gust Slash", r => Actionmanager.LastSpell.Name == "Spinning Edge"),
						Spell.Cast("Spinning Edge")
						)
					),
					
				//Defensives
				new Decorator(r => 
					Kupper.Settings.NinjaSettings.lastspellused == "Ninjutsu" && 
					!Core.Me.HasAura("Mudra") &&
					(SkillBlocker.Cooldown.TotalMilliseconds >= 1000 ||	Core.Me.CurrentTP <= 50), 
					
					new PrioritySelector(
						Spell.Cast("Invigorate", r => Core.Me.CurrentTPPercent <= settings.UseInvigorateTP, r => Core.Me),
						Spell.Cast("Second Wind", r => Core.Me.CurrentHealthPercent <= settings.UseSecondWindHP, r => Core.Me),
						Spell.Cast("Featherfoot", r => Core.Me.CurrentHealthPercent <= settings.UseFeatherfootHP, r => Core.Me)
						)
					),
				
				//OffGCDs
				new Decorator(r => 
				
					(SkillBlocker.Cooldown.TotalMilliseconds >= 1000 ||	Core.Me.CurrentTP <= 50) && 
					Kupper.Settings.NinjaSettings.lastspellused == "Ninjutsu" && 
					!Core.Me.HasAura("Mudra"),	
										
					new PrioritySelector(
						Spell.Cast("Assassinate", r => settings.UseAssassinate),
						Spell.Cast("Mug"),
						Spell.Cast("Jugulate", r => !settings.UseInterrupt && settings.UseJugulate)
//						UsePotion("Potent Poisoning Potion", Core.Me.CurrentTarget)
						)
					),
					
				//Goad				
				new Decorator(r => 
					Core.Me.ClassLevel >= 18 &&
					settings.UseGoad &&
					Goadtarget() != null &&
					(SkillBlocker.Cooldown.TotalMilliseconds >= 1000 ||	Core.Me.CurrentTP <= 50) && 
					Kupper.Settings.NinjaSettings.lastspellused == "Ninjutsu" && !Core.Me.HasAura("Mudra"),
					
					new PrioritySelector(
						Spell.Cast("Goad", r => Goadtarget().CurrentTP <= settings.UseGoadTP, r => Goadtarget())
						)
					)
			);
		}
		
    }
}